#ifndef _SHAPEFILE_H_INCLUDED
#define _SHAPEFILE_H_INCLUDED

/******************************************************************************
 * $Id: shapefil.h,v 1.26 2002/09/29 00:00:08 warmerda Exp $
 *
 * Project:  Shapelib
 * Purpose:  Primary include file for Shapelib.
 * Author:   Frank Warmerdam, warmerdam@pobox.com
 *
 ******************************************************************************
 * Copyright (c) 1999, Frank Warmerdam
 *
 * This software is available under the following "MIT Style" license,
 * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
 * option is discussed in more detail in shapelib.html.
 *
 * --
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 ******************************************************************************

 >>>>> Changelog removed from here <<<<< (Jon Valdes)

 */

#include <stdio.h>

#ifdef USE_DBMALLOC
#include <dbmalloc.h>
#endif

/************************************************************************/
/*                        Configuration options.                        */
/************************************************************************/

/* -------------------------------------------------------------------- */
/*      Should the DBFReadStringAttribute() strip leading and           */
/*      trailing white space?                                           */
/* -------------------------------------------------------------------- */
#define TRIM_DBF_WHITESPACE

/* -------------------------------------------------------------------- */
/*      Should we write measure values to the Multipatch object?        */
/*      Reportedly ArcView crashes if we do write it, so for now it     */
/*      is disabled.                                                    */
/* -------------------------------------------------------------------- */
#define DISABLE_MULTIPATCH_MEASURE

/************************************************************************/
/*                             SHP Support.                             */
/************************************************************************/
typedef	struct
{
	FILE	*fpSHP;
	FILE	*fpSHX;

	int		nShapeType;				/* SHPT_* */

	int		nFileSize;				/* SHP file */

	int		nRecords;
	int		nMaxRecords;
	int		*panRecOffset;
	int		*panRecSize;

	double	adBoundsMin[4];
	double	adBoundsMax[4];

	int		bUpdated;

	unsigned char *pabyRec;
	int		nBufSize;
} SHPInfo;

typedef SHPInfo * SHPHandle;

/* -------------------------------------------------------------------- */
/*      Shape types (nSHPType)                                          */
/* -------------------------------------------------------------------- */
#define SHPT_NULL	0
#define SHPT_POINT	1
#define SHPT_ARC	3
#define SHPT_POLYGON	5
#define SHPT_MULTIPOINT	8
#define SHPT_POINTZ	11
#define SHPT_ARCZ	13
#define SHPT_POLYGONZ	15
#define SHPT_MULTIPOINTZ 18
#define SHPT_POINTM	21
#define SHPT_ARCM	23
#define SHPT_POLYGONM	25
#define SHPT_MULTIPOINTM 28
#define SHPT_MULTIPATCH 31


/* -------------------------------------------------------------------- */
/*      Part types - everything but SHPT_MULTIPATCH just uses           */
/*      SHPP_RING.                                                      */
/* -------------------------------------------------------------------- */

#define SHPP_TRISTRIP	0
#define SHPP_TRIFAN	1
#define SHPP_OUTERRING	2
#define SHPP_INNERRING	3
#define SHPP_FIRSTRING	4
#define SHPP_RING	5

/* -------------------------------------------------------------------- */
/*      SHPObject - represents on shape (without attributes) read       */
/*      from the .shp file.                                             */
/* -------------------------------------------------------------------- */
typedef struct
{
	int		nSHPType;

	int		nShapeId; /* -1 is unknown/unassigned */

	int		nParts;
	int		*panPartStart;
	int		*panPartType;

	int		nVertices;
	double	*padfX;
	double	*padfY;
	double	*padfZ;
	double	*padfM;

	double	dfXMin;
	double	dfYMin;
	double	dfZMin;
	double	dfMMin;

	double	dfXMax;
	double	dfYMax;
	double	dfZMax;
	double	dfMMax;
} SHPObject;

/* -------------------------------------------------------------------- */
/*      SHP API Prototypes                                              */
/* -------------------------------------------------------------------- */
SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );
SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );

void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType, double * padfMinBound, double * padfMaxBound );

SHPObject *	SHPReadObject( SHPHandle hSHP, int iShape );

int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
void SHPDestroyObject( SHPObject * psObject );
void SHPComputeExtents( SHPObject * psObject );

SHPObject * SHPCreateSimpleObject( int nSHPType, int nVertices,double * padfX, double * padfY, double * padfZ );

SHPObject * SHPCreateObject( int nSHPType, int nShapeId,int nParts, int * panPartStart, int * panPartType,
		int nVertices, double * padfX, double * padfY,double * padfZ, double * padfM );

int SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );

void SHPClose( SHPHandle hSHP );

const char * SHPTypeName( int nSHPType );
const char * SHPPartTypeName( int nPartType );

/* -------------------------------------------------------------------- */
/*      Shape quadtree indexing API.                                    */
/* -------------------------------------------------------------------- */

/* this can be two or four for binary or quad tree */
#define MAX_SUBNODE	4

typedef struct shape_tree_node
{
	/* region covered by this node */
	double	adfBoundsMin[4];
	double	adfBoundsMax[4];

	/* list of shapes stored at this node.  The papsShapeObj pointers
	   or the whole list can be NULL */
	int		nShapeCount;
	int		*panShapeIds;
	SHPObject   **papsShapeObj;

	int		nSubNodes;
	struct shape_tree_node *apsSubNode[MAX_SUBNODE];

} SHPTreeNode;

typedef struct
{
	SHPHandle   hSHP;

	int		nMaxDepth;
	int		nDimension;

	SHPTreeNode	*psRoot;
} SHPTree;

SHPTree * SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,	double *padfBoundsMin, double *padfBoundsMax );
void SHPDestroyTree( SHPTree * hTree );

int SHPWriteTree( SHPTree *hTree, const char * pszFilename );
SHPTree SHPReadTree( const char * pszFilename );

int	SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
int	SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
int	SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );

void SHPTreeTrimExtraNodes( SHPTree * hTree );

int * SHPTreeFindLikelyShapes( SHPTree * hTree,	double * padfBoundsMin,	double * padfBoundsMax,	int * );
int SHPCheckBoundsOverlap( double *, double *, double *, double *, int );

/************************************************************************/
/*                             DBF Support.                             */
/************************************************************************/
typedef	struct
{
	FILE	*fp;
	int		nRecords;
	int		nRecordLength;
	int		nHeaderLength;
	int		nFields;
	int		*panFieldOffset;
	int		*panFieldSize;
	int		*panFieldDecimals;
	char	*pachFieldType;

	char	*pszHeader;

	int		nCurrentRecord;
	int		bCurrentRecordModified;
	char	*pszCurrentRecord;

	int		bNoHeader;
	int		bUpdated;
} DBFInfo;

typedef DBFInfo * DBFHandle;

typedef enum {
	FTString,
	FTInteger,
	FTDouble,
	FTLogical,
	FTInvalid
} DBFFieldType;

#define XBASE_FLDHDR_SZ       32

DBFHandle DBFOpen( const char * pszDBFFile, const char * pszAccess );
DBFHandle DBFCreate( const char * pszDBFFile );

int	DBFGetFieldCount( DBFHandle psDBF );
int	DBFGetRecordCount( DBFHandle psDBF );
int DBFAddField( DBFHandle hDBF, const char * pszFieldName,	DBFFieldType eType, int nWidth, int nDecimals );

DBFFieldType DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName, int * pnWidth, int * pnDecimals );

int DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);

int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
const char * DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
const char * DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField );
int DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField, int nFieldValue );
int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField, double dFieldValue );
int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField, const char * pszFieldValue );
int DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
int DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField, const char lFieldValue);
int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,	void * pValue );
const char * DBFReadTuple(DBFHandle psDBF, int hEntity );
int DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );

DBFHandle DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );

void DBFClose( DBFHandle hDBF );
char DBFGetNativeFieldType( DBFHandle hDBF, int iField );

#endif /* ndef _SHAPEFILE_H_INCLUDED */
